package com.jzo2o.health.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderRefundStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersRefundMapper;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import com.jzo2o.health.service.IOrdersCancelledService;
import com.jzo2o.health.service.IOrdersRefundService;
import com.jzo2o.health.service.IOrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单退款表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-12-15
 */
@Service
@Slf4j
public class OrdersRefundServiceImpl extends ServiceImpl<OrdersRefundMapper, OrdersRefund> implements IOrdersRefundService {

    @Resource
    private IOrdersService ordersService;

    @Resource
    private RefundRecordApi refundRecordApi;
    @Resource
    private IOrdersCancelledService ordersCancelledService;
    @Resource
    private IOrdersRefundService ordersRefundService;

    public void refund(OrdersCancelReqDTO ordersCancelReqDTO) {

        Orders orders = ordersService.getById(ordersCancelReqDTO.getId());
        ordersCancelledService.addCancelRecord(ordersCancelReqDTO);
        ordersRefundService.refund(orders);

    }

    public void refund(Orders orders) {
        boolean resultForOrders = ordersService.lambdaUpdate()
                .eq(Orders::getId, orders.getId())
                .set(Orders::getOrderStatus, OrderStatusEnum.CLOSED.getStatus())
                .set(Orders::getPayStatus, OrderPayStatusEnum.REFUNDING.getStatus())
                .update();
        if (!resultForOrders) {
            throw new DBException("更新订单状态失败");
        }
        //添加退款记录
        boolean save = this.save(OrdersRefund
                .builder()
                .id(orders.getId())
                .tradingOrderNo(orders.getTradingOrderNo())
                .realPayAmount(BigDecimal.valueOf(0.01))
                .build());
        if (!save) {
            throw new DBException("添加退款记录失败");
        }
        //申请退款

        ExecutionResultResDTO executionResultResDTO = refundRecordApi.refundTrading(orders.getTradingOrderNo(), BigDecimal.valueOf(0.01));
        if (executionResultResDTO == null) {
            throw new DBException("退款申请失败");
        }
        Integer refundStatus = executionResultResDTO.getRefundStatus();

        while (refundStatus == OrderRefundStatusEnum.REFUNDING.getStatus()) {
            executionResultResDTO = refundRecordApi.refundTrading(orders.getTradingOrderNo(), BigDecimal.valueOf(0.01));
            if (executionResultResDTO == null) {
                throw new DBException("退款申请失败");
            }
            if (executionResultResDTO.getRefundStatus() == OrderRefundStatusEnum.REFUNDING.getStatus()) {
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                refundStatus = executionResultResDTO.getRefundStatus();
            }
        }
        //更新退款状态
        boolean update = ordersService.lambdaUpdate().eq(Orders::getId, orders.getId())
                .set(Orders::getPayStatus, refundStatus == OrderRefundStatusEnum.REFUND_SUCCESS.getStatus()
                        ? OrderPayStatusEnum.REFUND_SUCCESS.getStatus()
                        : OrderPayStatusEnum.REFUND_FAIL.getStatus())
                .set(Orders::getRefundNo, executionResultResDTO.getRefundNo())
                .set(Orders::getRefundId, executionResultResDTO.getRefundId())
                .update();
        if (!update) {
            throw new DBException("更新订单状态失败");
        }
        log.info("退款申请结果：" + (refundStatus == OrderRefundStatusEnum.REFUND_SUCCESS.getStatus() ? "退款成功" : "退款失败"));
        //删除退款记录
        boolean removeById = this.removeById(orders.getId());
        if (!removeById) {
            throw new DBException("删除退款记录失败");
        }
        log.info("删除退款记录成功");
    }

}
